package com.ellfors.module_first.edge_effect

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.animation.DecelerateInterpolator
import android.widget.EdgeEffect
import androidx.core.view.forEach
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.ellfors.common.ext.logD
import com.ellfors.common.ext.logI

/**
 * @date: 2024/07/03
 * @author: ly
 * @Description: 带阻尼回弹效果的RecyclerView，这个还有点问题，不能直接使用
 */
class DampingRecyclerView : RecyclerView {

    private var isActionUp = true

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context, attrs, defStyleAttr
    )

    init {
        edgeEffectFactory = object : EdgeEffectFactory() {
            override fun createEdgeEffect(view: RecyclerView, direction: Int): EdgeEffect {
                return object : EdgeEffect(context) {

                    //对于RecyclerView列表而言，内容已经在顶部到达边界了，此时用户仍向下滑动时，会调用onPull方法及后续流程，来更新当前视图，提示用户已经到边界了。
                    override fun onPull(deltaDistance: Float) {
                        super.onPull(deltaDistance)
                        handlePull(deltaDistance)
                    }

                    //对于RecyclerView列表而言，内容已经在顶部到达边界了，此时用户仍向下滑动时，会调用onPull方法及后续流程，来更新当前视图，提示用户已经到边界了。
                    override fun onPull(deltaDistance: Float, displacement: Float) {
                        super.onPull(deltaDistance, displacement)
                        handlePull(deltaDistance)
                    }

                    private fun handlePull(deltaDistance: Float) {

                        "[DampingEdgeEffect] onPull".logD()

                        val sign = if (direction == DIRECTION_BOTTOM) -1 else 1
                        val translationYDelta = sign * width * deltaDistance * 0.8f
//                        translationY += translationYDelta
                        forEach {
                            if (it.isVisible) {
                                // 设置每个RecyclerView的子item的translationY属性
                                getChildViewHolder(it).itemView.translationY += translationYDelta
                            }
                        }
                    }

                    //对于上面的情况，用户松开了，不向下滑动了，此时释放拉动的距离，并刷新界面消失当前的图形界面。
                    override fun onRelease() {
                        super.onRelease()

                        "[DampingEdgeEffect] onRelease, [isActionUp] $isActionUp".logI()

                        if (isActionUp) {
//                            val animator = ValueAnimator.ofFloat(translationY, 0f).setDuration(500)
//                            animator.interpolator = DecelerateInterpolator(2.0f)
//                            animator.addUpdateListener { valueAnimator ->
//                                translationY = valueAnimator.animatedValue as Float
//                            }
//                            animator.start()

                            forEach {
                                //复位
                                ValueAnimator
                                    .ofFloat(getChildViewHolder(it).itemView.translationY, 0f)
                                    .setDuration(500)
                                    .apply {
                                        interpolator = DecelerateInterpolator(2.0f)
                                        addUpdateListener { valueAnimator ->
                                            getChildViewHolder(it).itemView.translationY =
                                                valueAnimator.animatedValue as Float
                                        }
                                        start()
                                    }
                            }
                        }
                    }

                    //用户过度滑动时，RecyclerView调用Fling方法，把内容到达边界后消耗不掉的距离传递给onAbsorb方法，让其显示图形界面提示用户已到达内容边界。
                    override fun onAbsorb(velocity: Int) {
                        super.onAbsorb(velocity)

                        "[DampingEdgeEffect] onAbsorb".logD()

                        val sign = if (direction == DIRECTION_BOTTOM) -1 else 1
//                val translationVelocity = sign * velocity * FLING_TRANSLATION_MAGNITUDE
                        if (isVisible) {
                            // 在这个可以做动画
                        }
                    }

                    override fun draw(canvas: Canvas?): Boolean {
                        // 设置大小之后，就不会有绘画阴影效果
                        setSize(0, 0)
                        return super.draw(canvas)
                    }
                }
            }
        }
    }

    override fun onTouchEvent(e: MotionEvent?): Boolean {
        when (e?.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                isActionUp = false
            }
            MotionEvent.ACTION_MOVE -> {
                isActionUp = false
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                isActionUp = true
            }
        }
        return super.onTouchEvent(e)
    }
}